home *** CD-ROM | disk | FTP | other *** search
- ;*******************************************************
- ;* *
- ;* Asynchronous communication driver *
- ;* (for null modem only) *
- ;* *
- ;* CopyRight (C) by Nicholas Poljakov. 1995. *
- ;* *
- ;*******************************************************
- .MODEL SMALL
-
- include i_s.inc
- include c:\m61\include\dos.inc
-
- public inbuff, in_cnt, sw_buff, err_cnt, open_type, b_size
- public out_buff, out_cnt, out_full, dcl1, dcl2, err1, lock_send, rcv_exit
- public rcv_off, rcv_seg, base_addr, port_num, save0b, save0c, tsrsize, my_psp
- public blocklt, startblock, ascom, quickexit, nextp, cnt01, fex, cnt00
- public ac_open, ac_opn_02, ac_opn_01, ac_opn_1, ac_opn_5, ac_opn_2, ac_opn_3
- public ac_opn_4, ac_opn_6, ac_opn_7, setcom1, setcom, ac_opn_retry, ac_opn_8
- public ac_opn_9, ac_opn_10, ac_opn_100, ac_opn_101, ac_mdm_act, ac_opn_11
- public ac_exit, ac_opn_exit, ac_close, ac_cls_01, ac_cls_02, ac_cls_03
- public ac_cls_0, ac_cls_exit, ac_send, sndproc, send_cycl, snd_retry, sndexit
- public sendal, send_cycxx, snd_retryx, int6e, int6e_start, popen, int6e_c0
- public int6e_c1, int6e_c2, int6e_c3, int6e_c4, ctl_send, when_ready5, int6e_c5
- public int6e_exit, io_int, next_int, testnext, receive, z_exit, savelt
- public rcvtest0, rcvcycl, rcvtest, callc, io_int_exit, int_exit
-
-
- .STACK 10h
-
- .DATA
-
- inbuff db 2048 dup (?)
- in_cnt dw 0 ;count of received bytes
- sw_buff db 0
- err_cnt db 0
- open_type db 0 ; 50h - open for PORT
- b_size db 0 ; size of block for transmition
- out_buff dd 0 ; out buffer address
- out_cnt dw 0 ; count of bytes that was send
- out_full dw 0 ; total of send bytes1
- dcl1 db 0ah, 0dh
- db 'Async. driver was already installed...$'
- dcl2 db 0ah, 0dh
- db 'Async. driver is installed.$'
- err1 DB 13,10,"Must have DOS 3.0 or higher",13,10,"$"
- lock_send db 0
- rcv_exit dd 0
- org rcv_exit
- rcv_off dw ?
- rcv_seg dw ?
- base_addr dw 0
- port_num db 0
- save0b db 4 dup (?)
- save0c db 4 dup (?)
- tsrsize dw 0
- my_psp dw 0
- BlockLT dw 0
- StartBlock db 0
-
- .CODE
- ;
- ascom PROC
- ;********************************************************
- ;* *
- ;* ASync. COMmunication *
- ;* *
- ;* Function: Installation of 6E interrupt handler. *
- ;* The int 6e routine was disigned to support*
- ;* the COM1 and COM2. *
- ;* *
- ;********************************************************
- mov ax, _DATA
- mov ds, ax
-
- ;
- ; Calculate Tsrsize
- ;
- mov bx, ss
- mov ax, es ; PSP address
- mov my_psp, ax
- sub bx, ax
- mov ax, sp
- mov cx, 4
- shr ax, cl ; convert to paragraphs
- add bx, ax
- inc bx ; one extra paragraph
- mov tsrsize, bx
- ;
- @GetVer ; Get DOS version
- cmp al,3 ; Requires DOS 3.0
- jge NextP
- @ShowStr err1 ; else error and quit
- QuickExit:
- @Exit
- ;
- NextP:
-
- ;*
- ;* Test if int6e also exist
- ;*
-
- mov ax,356eh
- int 21h
- push es
- pop ax
- cmp ax,0
- je cnt00
- cnt01:
- mov ah,3 ; check function
- int 6eh
- cmp al,55h ; is the int6e routine active ?
- jne cnt00 ; no...
- fex:
- mov dx, offset dcl1
- mov ah, 9
- int 21h
- jmp QuickExit
- cnt00:
- push ds
- mov ax, _DATA
- mov bx, 0ah
- mov dx, seg int6e
- mov ds, dx
- mov word ptr [bx], ax ; save ds for int6e routine
- ;
- mov dx, seg io_int
- mov ds, dx
- mov bx, 0ah
- mov word ptr [bx], ax ; save ds for io_int routine
- pop ds
- ;
- push ds ;ß«σαá¡∩Ѽ ds
- mov dx,offset int6e ;ds:dx π¬áºδóáεΓ ¡á »α«µÑñπαπ
- mov ax,seg int6e ;
- mov ds,ax ;
- mov al,6eh ;¡«¼Ñα óÑ¬Γ«αá ñ½∩ com1
- mov ah,25h ;Σπ¡¬µ¿∩ ¿º¼Ñ¡Ñ¡¿∩ óÑ¬Γ«αá
- int 21h ;¼Ñ¡∩Ѽ óÑ¬Γ«α »αÑαδóá¡¿∩
- pop ds
- ;
- mov dx, offset dcl2
- mov ah, 9
- int 21h
- ;
- mov ax, my_psp
- mov es, ax
- mov ax, word ptr es:[2ch]
- mov es, ax
- mov ax, 4900h
- int 21h ; Free the local environment
-
- mov dx, tsrsize
- mov ax,3100h
- int 21h
- ;
-
- ascom ENDP
-
- ;*****************************************************
- ;* *
- ;* O P E N function *
- ;* *
- ;* Input : in AH - function code. *
- ;* in AL - subfunction code *
- ;* Output : Return code. ( 0 - OK; -1 - error) *
- ;*****************************************************
-
- ac_open PROC
- ;*
- ;* ES:DX -> init_serial structure
- ;*
- mov bx,dx
- ;* Save rcv_exit subroutine entry
- mov ax, word ptr es:[bx + asc_rcv_exit]
- mov rcv_off, ax
- mov ax, word ptr es:[bx + asc_rcv_exit + 2]
- mov rcv_seg, ax
- ;
- ;---»«½πτáѼ íẫóδ⌐ áñαÑß com#
- mov al, byte ptr es:[bx + asc_parity]
- and al, 0f0h ; clear right bits
- mov cl, 4
- ror al, cl ; first four bits is com. port number
- mov port_num, al ; save com. port number
- cmp al, 2 ; high COM number (with int support)
- ja ac_opn_02
- dec al ; com. num - 1
- rol al, 1 ; (com - 1) * 2 - it's displacement in BIOS
- mov si, 0
- and ax, 00ffh
- add si, ax
- push es
- mov ax,40h ;es π¬áºδóáÑΓ ¡á «í½áßΓ∞ ñá¡¡δσ bios
- mov es,ax ;
- mov dx,es:[si] ;»«½πτáѼ íẫóδ⌐ áñαÑß com1
- pop es
- mov base_addr, dx
- cmp dx, 0
- jne ac_opn_01
- ac_opn_02:
- mov ax, 0ffffh ; rc = -1 port not present
- jmp ac_opn_exit
- ac_opn_01:
- ;---¿¡¿µ¿á½¿º¿απÑ¿ αÑú¿ßΓαδ ñѽ¿Γѽ∩ ߬«α«ßΓ¿ «í¼Ñ¡á
- add dx,3 ;π¬áºδóáѼ ¡á αÑú¿ßΓα ¬«¡Γα«½∩ ½¿¡¿¿
- in al, dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- mov al,10000000b ;πßΓá¡áó½¿óáѼ í¿Γ 7
- out dx,al ;»«ßδ½áѼ íá⌐Γ
- mov ax, word ptr es:[bx + asc_speed]
- mov cx, ax
- dec dx ;π¬áºδóáѼ ¡á ßΓáαΦ¿⌐ íá⌐Γ ñѽ¿Γѽ∩
- dec dx ;߬«α«ßΓ¿ «í¼Ñ¡á
- in al, dx
- mov ax, cx ; restory ax
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- mov al, ah
- out dx,al ;»«ßδ½áѼ ßΓáαΦ¿⌐ íá⌐Γ ñѽ¿Γѽ∩
- dec dx ;π¬áºδóáѼ ¡á ¼½áñΦ¿⌐ íá⌐Γ ñѽ¿Γѽ∩
- in al, dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- mov ax, cx ; restory ax
- out dx,al ;»«ßδ½áѼ ¼½áñΦ¿⌐ íá⌐Γ ñѽ¿Γѽ∩
- ;
- cmp open_type, 50h
- je ac_opn_2 ; 8 bits in word
- mov al, byte ptr es:[bx + asc_width]
- cmp al, 5
- jb ac_opn_1
- cmp al,8
- ja ac_opn_2
- jmp ac_opn_3
- ac_opn_1:
- mov al, 5
- jmp ac_opn_3
- ac_opn_5:
- mov ah, 2
- jmp ac_opn_4
- ac_opn_2:
- mov al, 8
- ac_opn_3:
- sub al, 5
- ;---¿¡¿µ¿á½¿º¿απѼ αÑú¿ßΓα ¬«¡Γα«½∩ ½¿¡¿¿
- mov ah, byte ptr es:[bx + asc_stops]
- cmp ah, 2
- ja ac_opn_5
- ac_opn_4:
- dec ah
- mov cl,2
- rol ah,cl
- or al,ah ; number stop-bits
- ;
- mov ah, byte ptr es:[bx + asc_parity]
- and ah, 0fh ; select partity
- cmp ah, 1
- jne ac_opn_6
- or al,00001000b
- jmp ac_opn_7
- ac_opn_6:
- cmp ah,2
- jne ac_opn_7
- or al,00011000b
- ac_opn_7:
- add dx,3 ;π¬áºδóáѼ ¡á αÑú¿ßΓα ¬«¡Γα«½∩ ½¿¡¿¿
- out dx,al ;»«ßδ½áѼ ¿¡¿µ¿á½¿ºáµ¿«¡¡«Ñ º¡áτÑ¡¿Ñ
- ;
- ;---¿¡¿µ¿á½¿º¿απѼ αÑú¿ßΓα αáºαÑΦÑ¡¿∩ »αÑαδóá¡¿∩
- ;
- mov al, byte ptr es:[bx + asc_parity]
- and al, 0f0h ; clear right bits
- push dx ; save dx
- cmp al, 10h ; is it COM1 ?
- je SetCom1 ; yes... goto SetCom1
- mov bx, 0bh * 4
- mov di, offset save0b
- jmp SetCom
- SetCom1:
- mov bx, 0ch * 4
- mov di, offset save0c
- ;
- ; Set int for COM#
- ;
- SetCom:
- mov ax,0
- cli
- push es
- push ds
- push ds
- pop es
- mov ds, ax
- mov si, bx
- mov cx, 4
- rep movsb
- pop ds
- pop es
- ;
- push es
- mov es, ax
- mov dx,offset io_int ;ds:dx π¬áºδóáεΓ ¡á »α«µÑñπαπ
- mov ax,seg io_int ;int async. processing
- mov es:[bx], dx
- mov es:[bx + 2], ax
- pop es
- sti
- pop dx
- ;
- ac_opn_retry:
- dec dx ;π¬áºδóáѼ ¡á αÑú¿ßΓα αáºαÑΦÑ¡¿∩
- dec dx ;»αÑαδóá¡¿∩
- in al, dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- cmp al, 0
- je ac_opn_8
- inc dx
- in al, dx
- inc dx
- inc dx
- inc dx ; line status
- in al, dx
- inc dx ; modem status
- in al, dx
- mov dx, base_addr
- in al, dx
- inc dx
- mov al, 0
- out dx, al
- inc dx
- inc dx
- jmp ac_opn_retry
- ac_opn_8:
- mov err_cnt, 0
- cli ; Disable interrupts
- in al,21h ; port 21h, 8259-1 int IMR
- and al,0E7h
- cmp port_num, 1 ; COM1 ?
- jne ac_opn_9 ; no it's COM2
- or al, 00001000b
- jmp short ac_opn_10
- ac_opn_9:
- or al, 00010000b
- ac_opn_10:
- out 21h,al ; port 21h, 8259-1 int comands
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- in al, 21h
- cmp port_num, 1 ; is't COM1 ?
- jne ac_opn_100 ; no it's COM2...
- test al, 00010000b ; it's COM1
- jz ac_opn_101
- and al, 11101111b
- out 21h, al
- jmp ac_opn_101
- ac_opn_100:
- test al, 00001000b
- jz ac_opn_101
- and al, 11110111b
- out 21h, al
- ac_opn_101:
- mov al,1 ;páºpÑΦáѼ »αÑαδóá¡¿∩
- out dx,al ;»«ßδ½áѼ íá⌐Γ
- inc dx
- inc dx
- inc dx
- ac_mdm_act:
- mov al, 0bh ; activate modem
- out dx, al
- inc dx
- inc dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- in al, dx
- dec dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- in al, dx
- test al, 0eh
- jz ac_exit
- test al, 00000001b
- jz ac_opn_11
- mov dx, base_addr
- in al, dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- inc dx
- in al, dx
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- mov al, 0
- out dx, al
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- mov al, 1
- out dx, al
- add dx, 3
- jmp ac_mdm_act
- ac_opn_11:
- dec dx
- inc err_cnt
- cmp err_cnt, 10
- ja ac_exit
- jmp ac_mdm_act
- ac_exit:
- sti ; Enable interrupts
- mov err_cnt, 0
- ;
- mov ax, 0 ; ret. code
- ac_opn_exit:
- ret
-
- ac_open ENDP
- ;
-
- ;*****************************************************
- ;* *
- ;* C L O S E function *
- ;* *
- ;* Input : in AH - function code. *
- ;* Output : Return code. ( 0 - OK; -1 - error) *
- ;*****************************************************
- ac_close PROC
- ;*
- ;* Close subroutine
- ;*
- ;* In al port number (1 or 2)
- ;*
- cmp al, port_num
- je ac_cls_01
- jmp ac_cls_exit
- ac_cls_01:
- cmp al, 1
- jne ac_cls_02
- mov di, 0bh * 4
- mov si, offset save0b
- jmp short ac_cls_03
- ac_cls_02:
- mov di, 0ch * 4
- mov si, offset save0c
- ac_cls_03:
- mov ax, 0
- push es
- mov es, ax
- mov cx, 4
- cli
- rep movsb
- pop es
- ;---»«½πτáѼ íẫóδ⌐ áñαÑß
- mov dx,base_addr ;»«½πτáѼ íẫóδ⌐ áñαÑß
- cmp dx,0
- jne ac_cls_0
- jmp ac_cls_exit
- ;
- ac_cls_0:
- inc dx
- mov al,0 ;ºá»pÑΘáѼ »αÑαδóá¡¿∩
- out dx,al ;»«ßδ½áѼ íá⌐Γ
- ac_cls_exit:
- sti
- ret
- ac_close ENDP
- ;
-
- ;*****************************************************
- ;* *
- ;* S E N D function *
- ;* *
- ;* Input : in AH - function code. *
- ;* in es:dx pointer to block; *
- ;* in cx - length of block *
- ;* *
- ;* Output : Return code. ( 0 - OK; -1 - error) *
- ;*****************************************************
- ac_send PROC
- and cx, cx ; is length valid ?
- jnz SndProc
- cmp cx, 2048
- jbe SndProc
- jmp SndExit
-
- SndProc:
- mov lock_send, 0 ; send no locking
- mov bx, offset out_buff
- mov word ptr [bx], dx ; save offset and
- mov word ptr [bx + 2], es ; segment of out buffer
- mov out_full, cx ; save out counter
- mov out_cnt, 0 ; initial value
- mov si, dx
- sti ; enable int.'s
- mov al, 65h ; send StartBlock indicator
- call SendAL
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
-
- mov al, cl ; send low byte of length
- call SendAl
- mov al, ch ; send high byte of length
- call SendAl
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
- jmp short $+2 ; delay for I/O
-
- send_cycl:
- cmp lock_send, 0 ; enable send ?
- jne send_cycl ; that must be replaced !!!
- mov ah, byte ptr es:[si]
- add dx, 5
- snd_retry:
- in al,dx
- test al,00100000b ; ready to send ?
- jz snd_retry
- sub dx, 5
- mov al, ah
- out dx, al
- dec out_full
- inc out_cnt
- inc si ; next byte
- ;
- loop send_cycl
- ;
- SndExit:
- ret
- ac_send ENDP
-
- ;***************************************************
- ;* Send Byte from AL *
- ;* *
- ;* Function : Send on async. port one byte. *
- ;* Input : In AL byte for send. *
- ;* *
- ;***************************************************
- SendAL PROC
- push ax
- mov dx, base_addr
- send_cycXX:
- cmp lock_send, 0 ; enable send ?
- jne send_cycXX ; that must be replaced !!!
- add dx, 5
- snd_retryX:
- in al,dx
- test al,00100000b ; ready to send ?
- jz snd_retryX
- sub dx, 5
- pop ax
- out dx, al
- ret
- SendAL ENDP
-
- ;*****************************************************
- ;* *
- ;* Int 6E handler *
- ;* *
- ;* Input : in AH - function code. *
- ;* (and for send function ) *
- ;* in ds:dx pointer to block; *
- ;* in cx - length of block *
- ;* *
- ;* Output : Return code. ( 0 - OK; -1 - error) *
- ;*****************************************************
-
- int6e PROC far
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
- push bp
-
- mov bp, sp
- ;
- jmp int6e_start
- dw 0
- int6e_start:
- push ds
- pop es ; change ds and es
- push ax
- mov bx, 0ah
- mov ax, word ptr cs:[bx]
- mov ds, ax ; restory ds
- pop ax
- cmp ah,0 ; "open" function ?
- jne int6e_c0
- mov open_type, al ; Open for "PORT"
- cmp al, 50h ; open for PORT ?
- je Popen
- mov ax, 0ffffh ; bad return code;
- jmp int6e_exit
- Popen:
- call ac_open
- jmp int6e_exit
- int6e_c0:
- cmp ah,1 ; "close" function ?
- jne int6e_c1
- call ac_close
- jmp int6e_exit
- int6e_c1:
- cmp ah,2 ; "send" function ?
- jne int6e_c2
- call ac_send
- jmp int6e_exit
- int6e_c2:
- cmp ah,3 ; "test" function ?
- jne int6e_c3
- mov al,55h
- int6e_c3:
- cmp ah,4 ; "Get stat" function ?
- jne int6e_c5
- cmp al, 0 ; Send status ?
- jne int6e_c4
- mov ax, out_full ; Rest bytes for send
- jmp int6e_exit
- int6e_c4:
- cmp al, 2 ; Send xoff ?
- jne int6e_exit
- mov out_full, 0
- mov al, 19h
- ctl_send:
- mov dx, base_addr
- add dx, 5 ; line status
- when_ready5:
- in al, dx
- test al, 00100000b ; ready to send ?
- jz when_ready5 ; retry
- sub dx, 5
- out dx, al
- jmp int6e_exit
- int6e_c5:
- cmp al, 3 ; Send xon ?
- jne int6e_exit
- mov out_full, 0
- mov al, 17h ; xon
- jmp ctl_send
- ;
- int6e_exit:
- pop bp
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- iret
- int6e ENDP
-
-
- ;*****************************************************
- ;* *
- ;* Handler for I/O interrupt *
- ;* *
- ;*****************************************************
-
- io_int PROC far
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
- ;
- jmp short $ + 4
- dw 0
- mov bx, 0ah
- mov ax, word ptr cs:[bx]
- mov ds, ax ; restory DS
- ;
- Next_int:
- mov dx, base_addr ;íẫóδ⌐ áñαÑß
- add dx, 2 ; int. identification
- in al, dx
- add dx, 3 ; line status
- in al, dx
- test al, 00001110b ; errors ?
- jz TestNext
- jmp io_int_exit
- TestNext:
- test al, 00000001b ; was byte received ?
- jnz receive
- jmp io_int_exit
- ;
- ;
- ; Receive subroutine
- ;
- ;
- receive:
- mov si, offset inbuff
- xor bx, bx
- sub dx, 4
- xor ax, ax
- out dx, al ; disable Com# interrupt
- dec dx
- in al, dx
- cmp StartBlock, 65h
- je SaveLt
- mov StartBlock, al
- Z_exit:
- inc dx
- mov al, 1 ; enable RECEIVE interrupt
- out dx, al
- jmp io_int_exit
- SaveLt:
- mov byte ptr BlockLT, al ; save low byte of length
- add dx,5 ;π¬áºδóáѼ ¡á αÑú¿ßΓα ßΓáΓπßá ½¿¡¿¿
- RcvTest0:
- in al,dx ;»«½πτáѼ íá⌐Γ ßΓáΓπßá
- test al,00000001b ;»α«óÑα∩Ѽ »«½πτÑ¡δ ½¿ ñá¡¡δÑ
- jz RcvTest0
- sub dx, 5
- in al,dx ;τ¿ΓáѼ »«½πτÑ¡¡δ⌐ ß¿¼ó«½
- mov byte ptr BlockLT + 1, al ; save high byte of length
-
- mov cx, BlockLT
- and cx, cx
- jnz RcvCycl
- mov StartBlock, 0
- jmp Z_exit
-
- RcvCycl:
- add dx,5 ;π¬áºδóáѼ ¡á αÑú¿ßΓα ßΓáΓπßá ½¿¡¿¿
- RcvTest:
- in al,dx ;»«½πτáѼ íá⌐Γ ßΓáΓπßá
-
- ; test al,00011110b ;»α«óÑα∩Ѽ ¡á «Φ¿í¬π
- ; jnz error_routine ;Ñß½¿ ñá, Γ« ¡á «íαáí«Γ¬π «Φ¿í¬¿
-
- test al,00000001b ;»α«óÑα∩Ѽ »«½πτÑ¡δ ½¿ ñá¡¡δÑ
- jz RcvTest
- sub dx, 5
- in al,dx ;τ¿ΓáѼ »«½πτÑ¡¡δ⌐ ß¿¼ó«½
- mov byte ptr [si + bx], al
- inc bx
-
- loop RcvCycl
- mov StartBlock, 0
- ;*
- ;* Block ready. Call EXIT routine
- ;*
- mov cx, bx
- mov dx, si
- CallC:
- ;
- push dx ; call
- push ds ; with "C"
- push cx ; convensions
- mov ax, 2
- pushf ; Call "_interrupt" function
- call rcv_exit
- add sp, 6
- ;
- mov b_size, 0 ; reset size of buffer
-
- mov dx, base_addr
- inc dx
- mov al, 1
- out dx, al ; enable RECEIVE interrupt
-
- io_int_exit:
- mov dx,base_addr ;íẫóδ⌐ áñαÑß
- inc dx ;π¬áºδóáѼ ¡á αÑú¿ßΓα ¿ñÑ¡Γ¿Σ¿¬áµ¿¿
- inc dx ;»αÑαδóá¡¿∩
- in al,dx ;τ¿ΓáѼ Ñú« º¡áτÑ¡¿Ñ
- test al,1 ;»α«óÑα∩Ѽ í¿Γ 1 (interrupt pending)
- jnz Int_exit
- jmp Next_int ;Ñß½¿ «¡ πßΓá¡«ó½Ñ¡, Γ« ¡á ¡áτὫ
-
- Int_exit:
- mov al, 20h
- out 20h, al
- ;
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- iret
- io_int ENDP
- ;
- END ascom
-